﻿#region Includes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using BrainTechLLC;
using System.IO;
#endregion

namespace AltSerializer.Tests
{
    [TestFixture(Description = "Tests for MiniLZO Port"), Category("MiniLZO")]
    public class MiniLZOTests
    {
        #region Class Variables
        #endregion

        #region Setup/Teardown

        /// <summary>
        /// Code that is run once for a suite of tests
        /// </summary>
        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {

        }

        /// <summary>
        /// Code that is run once after a suite of tests has finished executing
        /// </summary>
        [TestFixtureTearDown]
        public void TestFixtureTearDown()
        {

        }

        /// <summary>
        /// Code that is run before each test
        /// </summary>
        [SetUp]
        public void Initialize()
        {
        }

        /// <summary>
        /// Code that is run after each test
        /// </summary>
        [TearDown]
        public void Cleanup()
        {
        }
        #endregion

        #region Positive Tests

        [Test]
        public void CompressDecompressTextFile()
        {
            //Create a text file
            string textFile = Common.CreateBigDummyFile(Common.CurrentDir(), "TextFile.txt", 10000);

            //Read it in
            byte[] original = File.ReadAllBytes(textFile);

            //Compress it
            byte[] compressed = MiniLZO.Compress(original);

            //The compresed bytes must be less
            Assert.Less(compressed.Length, original.Length);

            //Decompress
            byte[] decompressed = MiniLZO.Decompress(compressed);

            //Compare all the bytes
            Assert.IsTrue(Common.BytesEqual(original, decompressed));
        }

        [Test]
        public void CompressDecompressBinaryFile()
        {
            //Create a binary file screen shot
            string binaryFile = Common.ScreenShot(Common.CurrentDir(), "Image.bmp");

            //Read it in
            byte[] original = File.ReadAllBytes(binaryFile);

            //Compress it
            byte[] compressed = MiniLZO.Compress(original);

            //The compresed bytes must be less
            Assert.Less(compressed.Length, original.Length);

            //Decompress
            byte[] decompressed = MiniLZO.Decompress(compressed);

            //Compare all the bytes
            Assert.IsTrue(Common.BytesEqual(original, decompressed));
        }

        [Test]
        public void CompressDecompressEmptyFile()
        {
            string emptyFile= Path.Combine(Common.CurrentDir(),"emptyfile.txt");

            File.WriteAllText(emptyFile, string.Empty);

            //Read it in
            byte[] original = File.ReadAllBytes(emptyFile);

            //Compress it
            byte[] compressed = MiniLZO.Compress(original);

            //Decompress
            byte[] decompressed = MiniLZO.Decompress(compressed);

            //Compare all the bytes
            Assert.IsTrue(Common.BytesEqual(original, decompressed));

        }

        [Test]
        public void CompressDecompressMemoryStream()
        {
            //Create a text file
            string textFile = Common.CreateBigDummyFile(Common.CurrentDir(), "TextFile.txt", 10000);

            //Read it in
            byte[] original = File.ReadAllBytes(textFile);

            //Write it to a memory stream
            MemoryStream mem = new MemoryStream();
            mem.Write(original, 0, original.Length);

            //Compress it
            byte[] compressed = MiniLZO.Compress(mem);

            //The compresed bytes must be less
            Assert.Less(compressed.Length, original.Length);

            //Decompress
            byte[] decompressed = MiniLZO.Decompress(compressed);

            //Compare all the bytes
            Assert.IsTrue(Common.BytesEqual(original, decompressed));
        }

        #endregion

        #region Expected Exceptions

        /// <summary>
        /// Should throw an ArgumentNullException if we pass in null 
        /// </summary>
        [Test]
        public void CompressNullBytes()
        {
            byte[] nullBytes= null;
            byte[] compressed = MiniLZO.Compress(nullBytes);
            Assert.AreEqual(nullBytes, compressed);
        }

        /// <summary>
        /// Should throw an ArgumentNullException if we pass in null
        /// </summary>
        [Test]
        public void DecompressNullBytes()
        {
            byte[] nullBytes = null;
            byte[] compressed = MiniLZO.Compress(nullBytes);
            byte[] decompressed = MiniLZO.Decompress(compressed);
            Assert.AreEqual(decompressed, compressed);
        }

        /// <summary>
        /// Should throw an ArgumentOutOfRangeException if the length is specified incorrectly
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void InvalidLength()
        {
            //Create a text file
            string textFile = Common.CreateBigDummyFile(Common.CurrentDir(), "TextFile.txt", 10000);

            //Read it in
            byte[] original = File.ReadAllBytes(textFile);

            //Compress it
            byte[] compressed = MiniLZO.Compress(original,original.Length+1);
        }

        /// <summary>
        /// Should throw an ArgumentOutOfRangeException if the start position is incorrect
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void InvalidStart()
        {
            //Create a text file
            string textFile = Common.CreateBigDummyFile(Common.CurrentDir(), "TextFile.txt", 10000);

            //Read it in
            byte[] original = File.ReadAllBytes(textFile);

            //Compress it
            byte[] compressed = MiniLZO.Compress(original,-1, original.Length);

        }
        #endregion
    }
}
